home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
tp_asm.exe
/
lha
/
DEMOTPA.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-07-22
|
7KB
|
198 lines
{═══════════════════════════════ DEMOTPA.PAS ═══════════════════════════════}
{ ────────────── TP&Asm Release 2.2 features demonstration ────────────── }
{ ─ Compile to Memory and F7 "Trace into" in the Version 5.0 or 5.5 IDE ─ }
{═══════════════════════════════════════════════════════════════════════════}
Program DemoTPA;
{$IFDEF VER50} Uses DOS,WchMgr50; {$ENDIF}
{$IFDEF VER55} Uses DOS,WchMgr55; {$ENDIF}
VAR TestW: Word;
{═══ The following Assembly Directive illustrates the "Asm" Statement ═══}
Procedure NearRet; Asm Ret;
Procedure First;
BEGIN {First Executable Statement of Procedure First}
{╔══ The following illustrates the ability to allocate and use "Local" ══╗}
{╚══ CSeg Data in the first TRUE Procedure or Function. ══╝}
Assemble
Stc
Jmp Start ; Short Jmp (EB 06) over data (01 00 02 00 03 00)
Dat Dw 1,2,3 ; FIRST Procedure can allocate and use CSeg Data.
Start: IF C Mov Ax,Dat ; Ax <-- 1
Cmc
IF C Mov Ax,$CEDE ; Ax will not change
Dec Ax ; Ax <-- 0
Here: IF Z Jmp There
Mov Bx,Dat+2 ; This statement won't execute
There:
Mov Cx,Dat+4 ; Cx <-- 3
End; {Assemble}
END; {Procedure First;}
{$F+} Procedure FarProc; BEGIN Writeln('FarProc'); END; {$F-}
Procedure NearProc; BEGIN Writeln('NearProc'); END;
Procedure FwdProc; Forward;
Procedure DosVersion; BEGIN Writeln('DemoTPA.DosVersion'); END;
Procedure TestProc;
Procedure NestProc; BEGIN WriteLn('NestProc'); END;
Procedure SubTest;
Label AsmLabel,PasLabel,PasForward,PastData;
BEGIN {First Executable Statement of SubTest}
{═════════════ The following illustrates the "Asm" statement ═════════════}
Asm Call First;
Assembly
;╔══ The following Pascal statement pushes the parent procedure's Bp ══╗
;║ before calling NestProc. Observe the Bp on the stack (above the ║
;║ Return Address) during NestProc and compare with the subsequent ║
;╚══ Assembly Call: ══╝
Pas NestProc;
;═══════ The following 2 assembly statements produce the same code: ═══════
Push [Bp+4] ;Push Parent Proc Bp as LAST 'Parameter'
Call NestProc;
;═════════════ The next two statements have the same result: ═════════════
Pas FwdProc;
Call FwdProc;
;╔═════ You can call near Proc/Functions within this Unit, or Far ═════╗
;╚═════ Proc/Functions within this or another Unit: ═════╝
Call NearProc
Call FarProc
Call DosVersion ;Unqualified reference to Proc in current module
Call Dos.DosVersion ;(Not available in version 4 DOS Unit)
Mov TestW,Ax ;Put Function Result into TestW
;══════ You can "Call" System Procedures using the "Pas" Statement: ═══════
Pas WRITELN('This WRITE statement called from within an assembly block');
Pas WRITELN('The DOS Version is ',Lo(TestW),'.',Hi(TestW));
END;
IF Testw = Dos.DosVersion THEN
WRITELN('This Pascal function call produced the same result');
{╔═══ Assembly labels which are defined in a "Label" statement can be ═══╗}
{╚═══ the target of a Pascal "Goto" statement: ═══╝}
Goto AsmLabel;
PasLabel:
Assemble
Xor Ax,Ax ;First Executable Statement following PasLabel
;═════ The Ds Register can be modified and restored using "SEG Data" ═════
Mov Ds,Ax ; Ds <-- 0
Mov Dx,SEG Data ; Dx <-- Program Data Segment
Mov Ds,Dx ; Restore Ds
FarBack:
Mov TestW,Cx ;First Executable Statement following FarBack
Push Cx
;═════════ A Pascal Label can be the target of an Assembly "Call" ═════════
Call PasForward
Pop Cx ;Call to PasForward will Return here
Cmp Cx,2
;╔═════════ Observe the change in "CPU.CsIp,p" for the next two ═════════╗
;╚═════════ jumps when Cx = 3 ═════════╝
jE ForwdFar ; This forward jump requires 5 bytes
jB ForwdNear ; This forward jump requires 2 bytes
Mov Ax,$1234
ForwdNear:
Jmp PastData
;══════ The following 140 bytes cannot be bridged with a short jump ═══════
db 20 dup 0
db 20 dup 0
db 20 dup 0
db 20 dup 0
db 20 dup 0
db 20 dup 0
db 20 dup 0
Pastdata:
;══════════════ Observe the Watch Expression "CPU.Flags-On" ══════════════
Std
Cld
Stc
Clc
ForwdFar:
Cli
Sti
Loop FarBack
;════════ The preceding Loop builds a 7 byte instruction sequence ════════
Jmp Finish
AsmLabel:
Call AsmProc
Jmp PasLabel
;═════════ A Pascal Label can be the target of an Assembly "Jmp" ═════════
AsmProc:
Mov Cx,3 ; Initialize Cx for the Loop
Ret
Finish:
END; {Assemble}
Exit;
PasForward:
WRITELN('This Pascal Label defines a callable "Procedure" terminated');
WRITELN('by the Inline/Assembly Directive "NearRet"; Counter = ',TestW);
NearRet;
End; {SubTest}
BEGIN
SubTest;
End; {TestProc}
Procedure FwdProc; BEGIN WriteLn('FwdProc'); END;
PROCEDURE SetAsmWatches;
BEGIN
{══════════════════════════════ SetAsmWatches ══════════════════════════════}
{- Displays all CPU Registers and Flags and a memory dump at the current -}
{- Stack Pointer and Instruction Pointer. This procedure is also defined -}
{- in the WCHMGR5x Units. It is reproduced here to illustrate the use of -}
{- the AddWatch procedure and the CPU record variable -}
{══════════════════════════════ SetAsmWatches ══════════════════════════════}
ClrWatch;
AddWatch(CopyRight);
{════════════ Type Definitions from WCHMGR5x.TPU ════════════
(The variable CPU below is of type CPUType)
TYPE FgBits = (C,X1,P,X3,A,x5,Z,S,T,I,D,O,X12,X13,X14,X15);
Const On = [X1,X3,X5,X12..X15];
TYPE W = ARRAY[0..32] OF WORD;
TYPE CPUType = RECORD
Case Integer OF
1: (Ax,Bx,Cx,Dx,Bp,Si,Di,Ds,Es,Ip,Cs,Fg,Sp,Ss :Word);
2: (Al,Ah,Bl,Bh,Cl,Ch,Dl,Dh : Byte);
3: (dum18 :Array[1..18] of byte;
CsIp : Pointer;
Flags : Set of FgBits;
SsSp : Pointer;);
END;
════════════════════════════════════════════════════════════}
ClrWatch;
AddWatch('CPU.CsIp^,m'); {- Hex Dump beginning at current instruction -}
AddWatch('CPU.CsIp,p'); {- Segment:Offset of the current instruction -}
AddWatch('W(CPU.SsSp^),$'); {- Memory Dump at current Stack Pointer -}
AddWatch('CPU.SsSp,p'); {- Segment:Offset of the Stack Pointer -}
AddWatch('CPU.Flags-On'); {- Current state of CPU Flags -}
AddWatch('CPU,$R'); {- Lists all register names and contents -}
END; {PROCEDURE SetAsmWatches}
BEGIN
SetAsmWatches; {- F7 Trace into or F8 Step over to set Assembly Watches -}
TestProc; {- Repeat F7 Trace into and watch registers and flags -}
END.